package app.vendorportal.web;

import app.vendorportal.domain.vendor.Vendor;
import app.vendorportal.domain.vendor.VendorUser;
import app.vendorportal.freemarker.tag.PermissionAllowTag;


import core.framework.exception.SessionTimeOutException;
import core.framework.util.JSONBinder;
import core.framework.web.request.RequestContext;
import core.framework.web.site.session.SecureSessionContext;
import core.framework.web.site.session.SessionContext;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.inject.Inject;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Raymond
 * @version createTime：May 8, 2013 1:31:50 PM
 */

@Component
public class SiteContext {

    private SessionContext sessionContext;
    private SecureSessionContext secureSessionContext;
    private RequestContext requestContext;
    private String serverUrl;

    public String getRelativeUrl() {
        return requestContext.relativeURL();
    }

    public Map<String, Object> getModel() {
        Map<String, Object> model = new HashMap<>();
        model.put("user", getUserName());
        model.put("company", getVendor().getVendorName());
        model.put(PermissionAllowTag.PERMISSIONVALUEKEY, getUser().getPermissionList().toString());

        return model;
    }

    public void login(VendorUser vendorUser) {
        sessionContext.set(SecureSessionConstants.LOGGED_IN, Boolean.TRUE);
        secureSessionContext.set(SecureSessionConstants.LOGGED_IN, Boolean.TRUE);
        String json = JSONBinder.toJSON(vendorUser);
        sessionContext.set(SecureSessionConstants.VENDORUSER_DETAILS, json);
        secureSessionContext.set(SecureSessionConstants.VENDORUSER_DETAILS, json);
    }

    public void setVendor(Vendor vendor) {
        String json = JSONBinder.toJSON(vendor);
        sessionContext.set(SecureSessionConstants.VENDOR_DETAILS, json);
        secureSessionContext.set(SecureSessionConstants.VENDOR_DETAILS, json);
    }

    public void signOut() {
        sessionContext.invalidate();
        secureSessionContext.invalidate();
    }

    public Vendor getVendor() {
        String json = requestContext.secure() ? secureSessionContext.get(SecureSessionConstants.VENDOR_DETAILS) : sessionContext.get(SecureSessionConstants.VENDOR_DETAILS);
        if (StringUtils.isBlank(json))
            throw new SessionTimeOutException("session timeout.");
        return JSONBinder.fromJSON(Vendor.class, json);
    }

    public VendorUser getUser() {
        String json = requestContext.secure() ? secureSessionContext.get(SecureSessionConstants.VENDORUSER_DETAILS) : sessionContext.get(SecureSessionConstants.VENDORUSER_DETAILS);
        // maybe not need
        if (StringUtils.isBlank(json))
            throw new SessionTimeOutException("session timeout.");
        return JSONBinder.fromJSON(VendorUser.class, json);
    }

    public String getUserName() {
        return getUser().getFirstName() + " " + getUser().getLastName();
    }

    public boolean loggedIn() {
        Boolean loggedIn = secureSessionContext.get(SecureSessionConstants.LOGGED_IN);
        return Boolean.TRUE.equals(loggedIn);
    }

    public void refresh(VendorUser user) {
        String json = JSONBinder.toJSON(user);
        sessionContext.set(SecureSessionConstants.VENDORUSER_DETAILS, json);
        secureSessionContext.set(SecureSessionConstants.VENDORUSER_DETAILS, json);
    }

    public String getServerUrl() {
        return serverUrl;
    }

    @Inject
    public void setSessionContext(SessionContext sessionContext) {
        this.sessionContext = sessionContext;
    }

    @Inject
    public void setSecureSessionContext(SecureSessionContext secureSessionContext) {
        this.secureSessionContext = secureSessionContext;
    }

    @Inject
    public void setRequestContext(RequestContext requestContext) {
        this.requestContext = requestContext;
    }

    @Inject
    public void setServerUrl(@Value("${portal.serverUrl}") String serverUrl) {
        this.serverUrl = serverUrl;
    }

}
